package com.geek.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;


@Service
public class LockService1 {


    /**
     * 使用lua脚本可以确保整个操作的原子性
     */
    private static String lockStr = "if redis.call('get', KEYS[1]) == false " +//判断是否已经上锁
            "    then " +
            "        redis.call('set',KEYS[1],ARGV[1],'nx','ex',ARGV[2]) " +//上锁
            "        return 1"+
            "    else " +
            "        return 0 " +
            "end";
    private static String unlockStr = "if redis.call('get', KEYS[1]) == ARGV[1] " +//判断是否有锁
            "    then " +
            "        redis.call('del',KEYS[1]) " +//解锁
            "        return 1"+
            "    else " +
            "        return 0 " +
            "end";


   @Autowired
   private RedisTemplate redisTemplate;



    public boolean lock(String key, String value, Long expired) {
        List<String> keys = Arrays.asList(key);

        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(lockStr, Long.class);

        Long execute = (Long) redisTemplate.execute(redisScript, new StringRedisSerializer(), new StringRedisSerializer(),
                keys, value, String.valueOf(expired));
        return execute == 1;
    }

    public boolean unLock(String key, String value) {
        List<String> keys = Arrays.asList(key);
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(unlockStr, Long.class);
        Long execute = (Long) redisTemplate.execute(redisScript, new StringRedisSerializer(), new StringRedisSerializer(),
                keys, value);
        return execute == 1;
    }
}